package com.anjie.powerproject.schedule;

import com.anjie.powerproject.common.Result;
import com.anjie.powerproject.common.StrategyTypeEnum;
import com.anjie.powerproject.entity.StrategyOutput;
import com.anjie.powerproject.entity.StrategyTemp;
import com.anjie.powerproject.service.StrategyOutputService;
import com.anjie.powerproject.service.StrategyTempService;
import com.anjie.powerproject.strategy.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 合并临时表工况到正式工况的定时任务
 * @deprecated 已过时，工况合并由python脚本负责
 */
@RestController
@RequestMapping(value = "schedule/merge")
public class MergeStrategySchedule {
    private static final Logger logger = LoggerFactory.getLogger(MergeStrategySchedule.class);

    @Autowired
    StrategyOutputService strategyOutputService;

    @Autowired
    StrategyTempService strategyTempService;

    @RequestMapping(value = "excute")
    public Result<Void> excute() {
        try {
            scheduleTask();
            return Result.ok(null);
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            return Result.error(String.format("[%s]", ex.getMessage()));
        }
    }


//    @Scheduled(cron = "0 0/1 * * * ?")
    private void scheduleTask() {
        logger.info("工况合并定时任务启动");

        Date now = new Date();
        // 读取今天的临时工况
        // 目前共有两种临时工况：1. 根据工况升级条件生成的临时工况 2. 根据气温变化自动生成的临时工况
        List<StrategyTemp> strategyTempsType1 = strategyTempService.getStrategyTempsByDateAndType(StrategyTypeEnum.DYNAMIC_UPDATE.getCode(), now);
        List<StrategyTemp> strategyTempsType2 = strategyTempService.getStrategyTempsByDateAndType(StrategyTypeEnum.WEATHER.getCode(), now);

        // 读取今天的正式工况
        List<StrategyOutput> strategyList = strategyOutputService.getStrategyOutputByDate(now);

        // 对上述三个列表根据时间去除已经成为历史的工况，并且进行排序
        strategyTempsType1 = strategyTempsType1.stream().filter(e -> DateUtils.after(e.getEndTime(), now)).sorted(Comparator.comparingLong(e -> e.getStartTime().getTime())).collect(Collectors.toList());
        strategyTempsType2 = strategyTempsType2.stream().filter(e -> DateUtils.after(e.getEndTime(), now)).sorted(Comparator.comparingLong(e -> e.getStartTime().getTime())).collect(Collectors.toList());
        strategyList = strategyList.stream().filter(e -> DateUtils.after(e.getEndTime(), now)).sorted(Comparator.comparingLong(e -> e.getStartTime().getTime())).collect(Collectors.toList());

        // 合并，需要注意的是两种临时工况的优先级(优先合并根据工况升级条件生成的临时工况)
        // 这里之后就是使用上面三个list来做diff，对于type1和type2覆盖的时间段，需要和strategyList中同样覆盖了的时间段进行合并，否则保持不变
        SimpleDateFormat format = DateUtils.ymdhFormat;
        Map<String, StrategyTemp> strategyTempsMap1 = strategyTempsType1.stream().collect(Collectors.toMap(e -> format.format(e.getStartTime()) + "|" + format.format(e.getEndTime()), e -> e, (v1, v2) -> v1));
        Map<String, StrategyTemp> strategyTempsMap2 = strategyTempsType2.stream().collect(Collectors.toMap(e -> format.format(e.getStartTime()) + "|" + format.format(e.getEndTime()), e -> e, (v1, v2) -> v2));
        strategyTempsMap1.putAll(strategyTempsMap2);

        for (StrategyOutput strategy : strategyList) {
            String timeSpan = format.format(strategy.getStartTime()) + "|" + format.format(strategy.getEndTime());
            StrategyTemp strategyTemp = strategyTempsMap1.get(timeSpan);

            if (strategyTemp != null) {
                String originStrategyInfo = strategy.getInfo();

                // 找到需要进行替换的工况
                strategy.setDeviceFrom(strategyTemp.getDeviceFrom());
                strategy.setDeviceTo(strategyTemp.getDeviceTo());
                strategy.setPower(strategyTemp.getPower());
                strategy.setStrategyType(strategyTemp.getStgyType());
                strategy.setInfo(strategyTemp.getInfo());

                strategyOutputService.save(strategy);

                logger.info("对工况id:{}进行合并，将工况由{} 调整为{}", strategy.getId(), originStrategyInfo, strategyTemp.getInfo());
            }
        }

    }
}
